package com.simple.portal.bo.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.simple.portal.bo.IMenuBO;
import com.simple.portal.bo.IUserInfoBO;
import com.simple.portal.dao.IUserGroupRelDAO;
import com.simple.portal.dao.IUserInfoDAO;
import com.simple.portal.vo.GroupInfoVO;
import com.simple.portal.vo.MenuVO;
import com.simple.portal.vo.OrganizationVO;
import com.simple.portal.vo.RightInfoVO;
import com.simple.portal.vo.UserGroupRelVO;
import com.simple.portal.vo.UserInfoVO;
import com.simple.util.RightInfoLoad;
import com.simple.util.common.Constants;
import com.simple.util.common.DateUtil;
import com.simple.util.common.EncryptUtil;
import com.simple.util.exception.SimpleApplicationException;
import com.simple.util.object.PageInfoBean;
import com.simple.util.object.portal.GroupRightBean;
import com.simple.util.object.portal.SessionUserBean;

@Service("userInfoBO")
@Transactional(propagation = Propagation.REQUIRED, readOnly = true)
public class UserInfoBOImpl implements IUserInfoBO {

	@Autowired
	private IUserInfoDAO userInfoDAO;
	
	@Autowired
	private IMenuBO menuBO;
	
	@Autowired
	private IUserGroupRelDAO userGroupRelDAO;
	
	
	@Override
	public UserInfoVO findById(String id) {
		return userInfoDAO.findById(id);
	}

	@Override
	public List<UserInfoVO> findAll() {
		return userInfoDAO.findAll();
	}
	
	@Override
	@Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor={Exception.class})
	public void editPassword(final UserInfoVO userInfoVO,final String password,final String passwordNew,final String passwordConfirm) throws SimpleApplicationException {
		
		final String encryptedPassword = EncryptUtil.passwordEncryptor(passwordNew);
		
		//校验原始密码输入是否正确
		if(!EncryptUtil.passwordCheck(password, userInfoVO.getPassword())){
			throw new SimpleApplicationException("message.user.self.editpassword.original.password.wrong");
		}
		//新密码和重复密码是否匹配
		if(!passwordNew.equals(passwordConfirm)){
			throw new SimpleApplicationException("message.user.self.editpassword.newpassword.notequal.confirmpassword");
		}
		//密码校验
		final String expr = "^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{"+Constants.USER_PASSWORD_LENGTH_MIN+","+Constants.USER_PASSWORD_LENGTH_MAX+"}$";
	    if(!passwordNew.matches(expr)){
	    	throw new SimpleApplicationException("message.user.self.editpassword.new.password.wrong",new String[]{String.valueOf(Constants.USER_PASSWORD_LENGTH_MIN),String.valueOf(Constants.USER_PASSWORD_LENGTH_MAX)} );
	    }
		
		
		userInfoVO.setPassword(encryptedPassword);
		userInfoVO.setInitPasswordFlag(Constants.STATE_NO);
		userInfoDAO.update(userInfoVO,Constants.LOGGER_OPERATE_FLAG_UPDATE,userInfoVO.getUserId());
	}
	
	@Override
	public List<UserInfoVO> findNullPasswordList() {
		return userInfoDAO.findNullPasswordList();
	}

	@Override
	public UserInfoVO findByLoginId(final String loginId) {
		return userInfoDAO.findByLoginId(loginId);
	}
	
	@Override
	public List<GroupInfoVO> findGroupInfoVOListByLoginId(String loginId){
		return userInfoDAO.findGroupInfoVOListByLoginId(loginId);
		
	}

	@Override
	public void checkLogin(final String inputPassword,final String loginId)  throws SimpleApplicationException {
		boolean isCheckFlag = false;
		UserInfoVO checkUserInfoVO=findByLoginId(EncryptUtil.encrypt(loginId));
		
		if(null == checkUserInfoVO){
			throw new SimpleApplicationException("message.login.loginid.not.exist");
		}else if(Constants.STATE_STOP.equals(checkUserInfoVO.getStatus())){
			throw new SimpleApplicationException("message.login.user.status.not.setup");
		}
		
		if (null != checkUserInfoVO.getPassword()) {
			isCheckFlag = EncryptUtil.passwordCheck(inputPassword,checkUserInfoVO.getPassword());
		}
		if (!isCheckFlag) {
			throw new SimpleApplicationException("message.login.password.error");
		}
	}

	@Override
	public OrganizationVO getOrganizationVOByLoginId(final String loginId) {
		return userInfoDAO.findOrganizationVOByLoginId(loginId);

	}

	@Override
	public SessionUserBean getSessionUserBeanByLoginId(String loginId) throws SimpleApplicationException  {
		
		
		SessionUserBean sessionUserBean = new SessionUserBean();
		
		String encryptLoginId=EncryptUtil.encrypt(loginId);
		
		UserInfoVO userInfoVO=findByLoginId(encryptLoginId);


		//get organization object by loginId
		OrganizationVO orgVO=getOrganizationVOByLoginId(encryptLoginId);
		if(null == orgVO || Constants.STATE_STOP.equals(orgVO.getStatus())){
			throw new SimpleApplicationException("message.login.user.organization.status.not.setup");
		}
		
		GroupInfoVO groupInfoVO =null;
		List<RightInfoVO> rightInfoVOListA=null;
		List<RightInfoVO> rightInfoVOListO=null;
		Map<String,List<MenuVO>> partnerMenuMap=null;
		
		Map<String,List<MenuVO>> commMenuMap=null;
	
		//if ORG TYPE IS 'P' ,get the first of the groupInfoVOList 
		List<GroupRightBean> groupRightBeanList =new ArrayList<GroupRightBean>();
		
		List<GroupInfoVO> groupInfoVOList=findGroupInfoVOListByLoginId(encryptLoginId);

		boolean groupFlag =false;
		
		for(GroupInfoVO groupInfoVOTemp : groupInfoVOList){
			
				groupInfoVO=groupInfoVOTemp;
	
				rightInfoVOListA=RightInfoLoad.getInstance().getAllByGroupIdAndRightFlag(groupInfoVO.getGroupId(), Constants.GROUP_RIGHT_FLAG_AUTHORIZATION);
				
				//get right info  by operation
				rightInfoVOListO=RightInfoLoad.getInstance().getAllByGroupIdAndRightFlag(groupInfoVO.getGroupId(), Constants.GROUP_RIGHT_FLAG_OPERATION);
				
				commMenuMap=menuBO.getMenuByRight(rightInfoVOListO);
				
				if(Constants.STATE_NORMAL.equals(groupInfoVOTemp.getStatus())){
					groupFlag = true;
					break;
				}
		}
		
		if(groupFlag){

			for(GroupInfoVO groupInfoVOTemp : groupInfoVOList){
				
				GroupRightBean groupRightBean =new GroupRightBean();
				
				List<RightInfoVO> rightInfoVOListOTemp= RightInfoLoad.getInstance().getAllByGroupIdAndRightFlag(groupInfoVOTemp.getGroupId(), Constants.GROUP_RIGHT_FLAG_OPERATION);
				
				List<RightInfoVO> rightInfoVOListATemp = RightInfoLoad.getInstance().getAllByGroupIdAndRightFlag(groupInfoVOTemp.getGroupId(), Constants.GROUP_RIGHT_FLAG_AUTHORIZATION);

				
				partnerMenuMap=menuBO.getMenuByRight(rightInfoVOListOTemp);

				groupRightBean.setGroupInfoVO(groupInfoVOTemp);
				groupRightBean.setRightInfoVOListO(rightInfoVOListOTemp);
				groupRightBean.setRightInfoVOListA(rightInfoVOListATemp);
				groupRightBean.setParentMenuVOList(partnerMenuMap.get("parentMenuVOList"));
				groupRightBean.setChildMenuVOList(partnerMenuMap.get("childMenuVOList"));
				groupRightBeanList.add(groupRightBean);
			}
			
			sessionUserBean.setUserInfoVO(userInfoVO);
			sessionUserBean.setOrganizationVO(orgVO);
			sessionUserBean.setGroupInfoVO(groupInfoVO);
			sessionUserBean.setRightInfoVOListA(rightInfoVOListA);
			sessionUserBean.setRightInfoVOListO(rightInfoVOListO);
			sessionUserBean.setParentMenuVOList(commMenuMap.get("parentMenuVOList"));
			sessionUserBean.setChildMenuVOList(commMenuMap.get("childMenuVOList"));
			sessionUserBean.setGroupRightBeanList(groupRightBeanList);
			
		}else{
			
			throw new SimpleApplicationException("message.login.user.group.status.not.setup");

		}

		return sessionUserBean;

	}
	
	@Override
	public List<UserInfoVO> findUserInfoByPage(String userId,
			String userIdSearch, String userNameSearch,
			String mobilePhoneSearch, String statusSearch,
			PageInfoBean pageInfoBean) {
		return userInfoDAO.findUserInfoByPage(userId, userIdSearch, userNameSearch, mobilePhoneSearch, statusSearch, pageInfoBean);
	}

	 @Override
	 @Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor={Exception.class})
	 public String addUserInfo(SessionUserBean sessionUserBean,
				UserInfoVO userInfoVO, String groupId, String siteLanguage) {
			String type=sessionUserBean.getOrganizationVO().getOrganizationType();
			String userId = sessionUserBean.getUserInfoVO().getUserId();
			String loginId = EncryptUtil.encrypt(userInfoVO.getLoginId());

			//encrypt LoginId
			userInfoVO.setLoginId(loginId);
			
			userInfoVO.setOrganizationId(sessionUserBean.getOrganizationVO().getOrganizationId());
			userInfoVO.setCreator(userId);
			userInfoVO.setCreateDate(DateUtil.getNowDate());
			userInfoVO.setUpdater(userId);
			userInfoVO.setUpdateDate(DateUtil.getNowDate());
			userInfoVO.setStatus(Constants.STATE_NORMAL);
			if(Constants.ORGANIZATION_TYPE_SYSTEM.equals(type)){
				userInfoVO.setUserType(Constants.USER_TYPE_SN);
			}
			
			userInfoVO.setInitPasswordFlag(Constants.STATE_YES);
			userInfoVO = userInfoDAO.save(userInfoVO, sessionUserBean.getUserInfoVO().getUserId());
			UserGroupRelVO userGroupRelVO = new UserGroupRelVO();
			userGroupRelVO.setGroupId(groupId);
			userGroupRelVO.setUserId(userInfoVO.getUserId());
			userGroupRelDAO.save(userGroupRelVO);
			return loginId;
		}

	@Override
	@Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor={Exception.class})
	public void update(SessionUserBean sessionUserBean, UserInfoVO userInfoVO,
			String groupId) {
//		userGroupRelDAO.findByUserId(userId);
		String userId = sessionUserBean.getUserInfoVO().getUserId();
		UserInfoVO formerUserInfoVO = findById(userInfoVO.getUserId());
		
//		userInfoVO.setOrganizationId(formerUserInfoVO.getOrganizationId());
//		userInfoVO.setLoginId(formerUserInfoVO.getLoginId());
//		userInfoVO.setPassword(formerUserInfoVO.getPassword());
//		userInfoVO.setStatus(formerUserInfoVO.getStatus());
//		userInfoVO.setInitPasswordFlag(formerUserInfoVO.getInitPasswordFlag());
//		userInfoVO.setUserType(formerUserInfoVO.getUserType());
//		userInfoVO.setCreator(formerUserInfoVO.getCreator());
//		userInfoVO.setCreateDate(formerUserInfoVO.getCreateDate());
		formerUserInfoVO.setUsername(userInfoVO.getUsername());
		formerUserInfoVO.setMobilePhone(userInfoVO.getMobilePhone());
		formerUserInfoVO.setOfficePhone(userInfoVO.getOfficePhone());
		formerUserInfoVO.setOfficeFax(userInfoVO.getOfficeFax());
		formerUserInfoVO.setEmailAddress(userInfoVO.getEmailAddress());
		formerUserInfoVO.setIm(userInfoVO.getIm());
		formerUserInfoVO.setMemo(userInfoVO.getMemo());
		
		formerUserInfoVO.setUpdater(userId);
		formerUserInfoVO.setUpdateDate(DateUtil.getNowDate());
		
		userInfoDAO.update(formerUserInfoVO, Constants.LOGGER_OPERATE_FLAG_UPDATE, sessionUserBean.getUserInfoVO().getUserId());
		List<UserGroupRelVO> userGroupRelVOList = userGroupRelDAO.findByUserId(formerUserInfoVO.getUserId());
		UserGroupRelVO userGroupRelVO = userGroupRelVOList.get(0);
		userGroupRelVO.setGroupId(groupId);
		userGroupRelDAO.update(userGroupRelVO);
	}

	@Override
	@Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor={Exception.class})
	public void controlUserInfo(SessionUserBean sessionUserBean, String userId,
			String status) {
		String operateFlag=Constants.STATE_NORMAL.equals(status) ? Constants.LOGGER_OPERATE_FLAG_START:Constants.LOGGER_OPERATE_FLAG_STOP;
		UserInfoVO formerUserInfoVO = findById(userId);
		formerUserInfoVO.setStatus(status);
		formerUserInfoVO.setUpdater(sessionUserBean.getUserInfoVO().getUserId());
		formerUserInfoVO.setUpdateDate(DateUtil.getNowDate());
		userInfoDAO.update(formerUserInfoVO,operateFlag,sessionUserBean.getUserInfoVO().getUserId());
	}


}
